﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Bounce
{
    class Ball
    {
        public float x;
        public float y;
        public float r;
        public float v_x;
        public float v_y;
    }

    public partial class Form1 : Form
    {
        Timer t;
        const float g = 9.8F;
        const float bounce_ratio = 0.9F;

        Ball b;

        float min_x;
        float max_x;
        float min_y;
        float max_y;

        int interval;

        BufferedGraphics myBuffer;

        public Form1()
        {
            InitializeComponent();
            t = new Timer();
            b = new Ball();
            b.r = 3;
            b.x = this.Width / 2;
            b.y = b.r;
            b.v_x = 200;
            b.v_y = 0;
            interval = 10;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Graphics gt = this.CreateGraphics();
            //缓冲绘图
            BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
            myBuffer = currentContext.Allocate(gt, new System.Drawing.Rectangle(0, 0, this.Width, this.Height));
            this.BackColor = Color.White;

            min_x = b.r;
            max_x = this.Width - b.r;
            min_y = + b.r;
            max_y = + this.Height - b.r;
            t.Tick += OnTimeOut;
            t.Interval = 2000;
            t.Start();
        }

        private void OnTimeOut(object sender, EventArgs e)
        {
            //StartAnimate();
            t.Stop();
            t.Interval = interval;
            t.Tick -= OnTimeOut;
            t.Tick += UpdateView;
            t.Start();
        }

        private void UpdateView(object sender, EventArgs e)
        {
            UpdateObj();
            DrawObj();
        }

        private void UpdateObj()
        {
            b.x += b.v_x * interval / 1000;
            b.y += b.v_y * interval / 1000;
            // x border
            if(b.x > max_x) // right border
            {
                b.v_x = -b.v_x * bounce_ratio;
                b.x = max_x;
            }else if(b.x < min_x)
            {
                b.v_x = -b.v_x * bounce_ratio;
                b.x = min_x;
            }
            //y border
            if (b.y > max_y) // right border
            {
                b.v_y = -b.v_y * bounce_ratio;
                b.y = max_y;
            }
            else if (b.y < min_y)
            {
                b.v_y = -b.v_y * bounce_ratio;
                b.y = min_y;
            }
            // update v_y
            b.v_y += g;
        }

        private void DrawObj()
        {
            
            Graphics g = myBuffer.Graphics;
            //设置平滑属性
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
            this.SetStyle(ControlStyles.DoubleBuffer, true);//设置双缓冲，防止图像抖动 
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);// 忽略系统消息，防止图像闪烁
            g.Clear(this.BackColor);
            //获取画笔
            Pen mypen = new Pen(Color.Black, 2f);
            g.DrawEllipse(mypen, b.x - b.r, b.y - b.r, b.r * 2, b.r * 2);
            g.DrawLine(mypen,
                this.Width / 2, 0,
                this.Width / 2, this.Height);
            //myBuffer.Render(g);
            this.Refresh();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            myBuffer.Render(e.Graphics);
        }
    }
}
